RT

您所在的位置:网站首页 rt thread系统支持多任务 RT

RT

2023-09-25 19:34| 来源: 网络整理| 查看: 265

先讨论当最大优先级数量小于等于 32 的情况。

rt_thread_ready_priority_group 是一个 32 bit的变量,每一个比特对应着一个优先级,比如第 0 位对应着优先级 0,该位为1,说明有优先级0的线程正在就绪,数字越小优先级越高。

那么问题了,当同时有多个不同线程同时就绪时,如何找到优先级最高的线程?

先看看,如果是 8bit的变量,如何查找到最低位的 1 RT-Thread 使用的是位图查询的方法,这是一种空间换时间的一种策略,也就是维护如下的查询数组:

const rt_uint8_t __lowest_bit_bitmap[] = { /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };

8bit的变量,意味着有256种情况,所以这是一个256大小的数组,数组的内容是无论你输入0-255之间哪个数,就能返回最低的那一位所处的位置,这样我们就能够在 O(1) 的时间内得到最高优先级的结果。

那么32位也就简单了,我们要不也搞一个这样的数组?算一下如果要满足要求,需要 2^32 * byte = 4GB 的存储空间,各位单片机的那弱小的身板怎么扛得住?

RT-Thread 采取是将 32bit 拆成 4 个 8bit,这样就能省不少空间,看一下 RT-Thread 是如何实现的?

int __rt_ffs(int value) { if (value == 0) return 0; if (value & 0xff) return __lowest_bit_bitmap[value & 0xff] + 1; if (value & 0xff00) return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9; if (value & 0xff0000) return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17; return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25; }

其实也就是多加了几个判断,虽不能一步到位,但也算是一种比较好的折中的方法吧。

查找当前最高优先级的方法如下:

highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;

当线程的优先级数量大于 32 时(RT-Thread最大支持到 256,这个数量绝对够用了)

针对这种情况,RT-Thread 采用的是二级位图的算法。

我们看源码,可以知道,此时多定义了 rt_thread_ready_table[32] 这个数组,用 bit 的视角来看,也就是 32*8 = 256 bit,就是优先级的最大数量。

其实 rt_thread_ready_table[32] 此时就充当着标识此时哪一个优先级有任务就绪的角色。

而 rt_thread_ready_priority_group 这个32位的变量就充当一个查找 rt_thread_ready_table[32] 这个32大小的数组哪一个字节有线程处在就绪状态。

此时查找最高优先级的算法如下:

register rt_ubase_t number; //先找到最高优先级处在rt_thread_ready_table[number]哪个位置 number = __rt_ffs(rt_thread_ready_priority_group) - 1; //再结合 number 和 rt_thread_ready_table 得到最高优先级 //右移3位相当于乘8 highest_ready_priority = (number


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3